package database

import "fmt" // 用于格式化错误信息

/*
本文件实现了数据库工厂（Factory），用于根据配置信息动态创建不同类型的数据库实例（如MySQL、Redis），
封装数据库的创建逻辑，实现"根据配置生成实例"的解耦，便于新增数据库类型时的扩展。
*/

// Factory 数据库工厂结构体，负责根据配置信息创建对应的数据库实例，
// 封装了数据库类型的判断和实例化逻辑，是工厂模式的具体实现
type Factory struct{}

// NewFactory 创建一个数据库工厂实例，用于后续创建数据库实例
// 返回值：
//
//	*Factory: 初始化后的数据库工厂实例
func NewFactory() *Factory {
	return &Factory{}
}

// CreateDatabase 根据数据库配置创建对应的数据库实例（仅创建实例，不自动连接）
// 参数：
//
//	config: 数据库配置结构体指针，包含数据库类型（Type）等信息
//
// 返回值：
//
//	Database: 创建的数据库实例（实现了Database接口）
//	error: 成功返回nil；配置的数据库类型不支持时返回错误
func (*Factory) CreateDatabase(config *Config) (Database, error) {
	// 根据配置中的数据库类型（Type），创建对应的实例
	switch config.Type {
	case DBTypeMySQL:
		// 若类型为MySQL，创建MySQL数据库实例
		return NewMySQLDatabase(config), nil
	case DBTypeRedis:
		// 若类型为Redis，创建Redis数据库实例
		return NewRedisDatabase(config), nil
	default:
		// 若类型不支持，返回错误信息
		return nil, fmt.Errorf("unsupported database type: %s", config.Type)
	}
}

// CreateDatabaseFromConfig 根据配置创建数据库实例，并自动建立连接，加入数据库管理中
// 参数：
//
//	name: 数据库的标识名称（当前代码未使用，可能为预留参数，用于后续扩展如关联管理器中的名称）
//	config: 数据库配置结构体指针
//
// 返回值：
//
//	Database: 已创建并连接成功的数据库实例
//	error: 成功返回nil；创建失败或连接失败时返回错误
func (f *Factory) CreateDatabaseFromConfig(manager *Manager, name string, config *Config) (Database, error) {
	// 先调用CreateDatabase创建实例
	db, err := f.CreateDatabase(config)
	if err != nil {
		return nil, err // 创建实例失败，返回错误
	}

	// 自动建立数据库连接
	if err := db.Connect(); err != nil {
		return nil, err // 连接失败，返回错误
	}
	// 将数据库添加到管理器
	if err := manager.AddDatabase(name, db); err != nil {
		err1 := db.Disconnect() // 如果添加失败，断开连接
		if err1 != nil {
			return nil, fmt.Errorf("failed to disconnect database: %s and %s", err, err1)
		}
		return nil, err
	}

	return db, nil // 返回已连接的实例
}
